/**
 * Created by Eran on 2015/11/16.
 */
package copyengine.resource.resProxy.cacheData
{
    import copyengine.log.CELog;
    import copyengine.resource.resProxy.CEResFIleDesc;
    import copyengine.utils.GeneralUtils;

    import flash.display.Bitmap;
    import flash.display.Loader;
    import flash.events.Event;
    import flash.events.IOErrorEvent;
    import flash.events.ProgressEvent;
    import flash.net.URLLoader;
    import flash.net.URLLoaderDataFormat;
    import flash.net.URLRequest;
    import flash.system.ImageDecodingPolicy;
    import flash.system.LoaderContext;
    import flash.utils.ByteArray;

    import starling.textures.Texture;

    public class CETextureResCacheData extends CEResCacheDataBasic
    {
        private var mImageLoader:Loader;
        private var mByteArrayLoader:URLLoader;

        protected var mTexture:Texture;

        //判断当前是否已经加载过,如果已经加载过在处理纹理丢失的时候
        //第二次就不会回调父类的onResLoadComplete函数
        private var mIsAlreadyLoaded:Boolean = false;

        public function CETextureResCacheData() {
        }

        override protected function doLoadRes():void {
            startHandleTextureLoad();
        }

        //===================================//
        //==Load数据到显存&处理LostContext
        //===================================//
        protected final function startHandleTextureLoad():void {
            if (mFileDesc.isHaveExtValue(CEResFIleDesc.EXT_CACHE_BYTE_A) && mFileDesc.getExtValue(CEResFIleDesc.EXT_CACHE_BYTE_A) != null) {
                handleByteArrayData(mFileDesc.getExtValue(CEResFIleDesc.EXT_CACHE_BYTE_A));
            } else {
                //从网上或者app目录以二进制形式load数据
                mByteArrayLoader = new URLLoader();
                mByteArrayLoader.dataFormat = URLLoaderDataFormat.BINARY;
                mByteArrayLoader.addEventListener(Event.COMPLETE, onByteArrayLoadComplete);
                mByteArrayLoader.addEventListener(ProgressEvent.PROGRESS, onLoadInProgress);
                mByteArrayLoader.addEventListener(IOErrorEvent.IO_ERROR, onLoadInError);
                mByteArrayLoader.load(new URLRequest(mFileDesc.filePath));
            }
        }

        private function onByteArrayLoadComplete(e:Event):void {
            handleByteArrayData(mByteArrayLoader.data as ByteArray);
        }

        private function handleByteArrayData(_byteArray:ByteArray):void {
            if (mFileDesc.isHaveExtValue(CEResFIleDesc.EXT_TEXTURE_IS_ATF) && mFileDesc.getExtValue(CEResFIleDesc.EXT_TEXTURE_IS_ATF) == true) {
                handleATFByteArray(_byteArray);
            }
            else {
                var lc:LoaderContext = new LoaderContext();
                lc.imageDecodingPolicy = ImageDecodingPolicy.ON_LOAD;
                mImageLoader = new Loader();
                mImageLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, onImageLoadComplete);
                mImageLoader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, onLoadInProgress);
                mImageLoader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, onLoadInError);
                mImageLoader.loadBytes(_byteArray, lc);
            }
        }

        private function onLoadInProgress(e:Event):void {}

        private function onLoadInError(e:Event):void {}


        //==================
        //== ATF 的处理
        //==================
        private function handleATFByteArray(_byteArray:ByteArray):void {
            if (mTexture == null) {
                //异步上传显存
                mTexture = Texture.fromAtfData(_byteArray, 1, false, onTextureHandleComplete);
                mTexture.root.onRestore = startHandleTextureLoad;
            }
            else {
                mTexture.root.uploadAtfData(_byteArray, 0, onTextureHandleComplete);
            }
        }

        //======================//
        //== PNG & JPG
        //======================//

        private function onImageLoadComplete(e:Event):void {
            var bitmap:Bitmap = e.target.content;

            try {
                //如果Bitmap损坏可以取到width及height信息,但是getPixel函数是无法使用的
                //所以此处用该函数检测Bitmap的完整性
                var testValue:uint = bitmap.bitmapData.getPixel(0, 0);
            } catch (e:Error) {
                //如果使用缓存且BitmapData文件发生损坏以后
                //从网上再次Load一份
                if (mFileDesc.extData != null) {
                    removeAllListener();
                    startHandleTextureLoad();
                }
                return;
            }

            if (mTexture == null) {
                //第一次load到显存中
                mTexture = Texture.fromBitmap(bitmap, false);
                mTexture.root.onRestore = startHandleTextureLoad;
            }
            else {
                //处理LostContext
                mTexture.root.uploadBitmap(bitmap);
            }

            //清空内存
            bitmap.bitmapData.dispose();
            bitmap = null;
            removeAllListener();
            //Texture处理完成
            onTextureHandleComplete();
        }

        //========================//
        //==Private  Function
        //=========================//

        private function removeAllListener():void {
            removeByteArrayListener();
            removeImageListener();
        }

        /**
         * Atlas继承自该类,Dispose时候需要调用该函数
         */
        protected final function removeByteArrayListener():void {
            if (mByteArrayLoader != null) {
                mByteArrayLoader.removeEventListener(Event.COMPLETE, onByteArrayLoadComplete);
                mByteArrayLoader.removeEventListener(ProgressEvent.PROGRESS, onLoadInProgress);
                mByteArrayLoader.removeEventListener(IOErrorEvent.IO_ERROR, onLoadInError);
                mByteArrayLoader = null;
            }
        }

        private function removeImageListener():void {
            if (mImageLoader != null) {
                GeneralUtils.removeTargetEventListener(mImageLoader.contentLoaderInfo, Event.COMPLETE, onImageLoadComplete);
                GeneralUtils.removeTargetEventListener(mImageLoader.contentLoaderInfo, ProgressEvent.PROGRESS, onLoadInProgress);
                GeneralUtils.removeTargetEventListener(mImageLoader.contentLoaderInfo, IOErrorEvent.IO_ERROR, onLoadInError);
                mImageLoader = null;
            }
        }

        //============================================//
        //==OverrideAble  Function
        //============================================//

        /**
         *处理完纹理信息后调用该函数，处理过程有可能为第一次创建好Texture或者处理完LostContext
         */
        protected function onTextureHandleComplete():void {
            removeAllListener();
            if (!mIsAlreadyLoaded) {
                mIsAlreadyLoaded = true;
                onResLoadComplete();
            }
        }

        override public function getData():* { return mTexture; }


        override protected function dispose():void {
            if (mLoadStatus == LOAD_STATUS_LOADED) {
                mTexture.dispose();
                mTexture = null;
                CELog.log("Texture of : " + mFileDesc.fileName + " has been dispose");
            } else {
                removeAllListener();
                CELog.err("Can not release texture data as the file : " + mFileDesc.fileName + " not been loaded yet");
            }
            super.dispose();
        }
    }


}
